package com.gitee.jiaojinxin.oauth2.auth.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.JdbcUserDetailsManager;

import javax.sql.DataSource;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

//    @Autowired
//    private DataSource dataSource;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 代码中存储用户的几种实现：1. 内存中；2. 数据库（默认的表机构和实现）；3. ldap；4. 数据库（自定义表结构和实现）；

        // 1：内存中
//        auth.inMemoryAuthentication()
//                .withUser("admin").password(passwordEncoder.encode("admin")).roles("ADMIN")
//                .and()
//                .withUser(User.builder().username("user").password(passwordEncoder.encode("user")).roles("USER").build())
//                .passwordEncoder(passwordEncoder);

        // 2：数据库中 表结构SQL：users.ddl
//        JdbcUserDetailsManager userDetailsService = auth.jdbcAuthentication()
//                .passwordEncoder(passwordEncoder)
//                .dataSource(dataSource)
//                .getUserDetailsService();
//        if (!userDetailsService.userExists("admin")) {
//            userDetailsService.createUser(
//                    User.builder()
//                            .username("admin")
//                            .password(passwordEncoder.encode("admin"))
//                            .roles("ADMIN")
//                            .build()
//            );
//        }
//        if (!userDetailsService.userExists("user")) {
//            userDetailsService.createUser(
//                    User.builder()
//                            .username("user")
//                            .password(passwordEncoder.encode("user"))
//                            .roles("USER")
//                            .build()
//            );
//        }

        // 3. ldap 暂未研究
//        auth.ldapAuthentication();

        // 4：自定义
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/images/**", "/css/**", "/font-awesome-4.7.0/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 所有请求开启认证
                .anyRequest().authenticated()
                .and()
                // 表单登录
                .formLogin()
                // 未登录跳转的登录页面，不配置则使用默认页面，即"/login"
                .loginPage("/login.html")
                // 登陆url（POST请求），若不配置，默认为loginPage的值
                .loginProcessingUrl("/doLogin")
                /**
                 * 登陆成功后，重定向地址，无论登陆前来自哪个地址，均重定向到该地址
                 * 注：该地址不能用GetMapping，因为登陆为POST，重定向地址为GET请求会报错
                 */
//                .successForwardUrl("/success")
                /**
                 * 登陆成功后，服务端跳转地址，
                 * 若alwaysUse=true，则无论登陆前来自哪个地址，登陆后均跳转该地址；
                 * 若=false，则登陆前在哪，登陆后跳转哪，直接跳转登陆页面登陆，则跳转该请求
                 */
//                .defaultSuccessUrl("/success")
//                .defaultSuccessUrl("/success", true)
                // 登陆成功后处理
//                .successHandler((request, response, authentication)->response.getWriter().write("successHandler"))
                // 登陆失败跳转地址
//                .failureUrl("/fail")
                // 登陆失败后重定向
//                .failureForwardUrl("/fail")
                // 登陆失败后处理
//                .failureHandler((request, response, exception)->response.getWriter().write("failureHandler"))
                // 登陆相关的放行
                .permitAll()
//                .and()
//                .logout()
                // 退出的url
//                .logoutUrl("/doLogout")
                // 退出请求
//                .logoutRequestMatcher(new AntPathRequestMatcher("/doLogout", "GET"))
                // 退出成功跳转地址
//                .logoutSuccessUrl("/success")
//                .permitAll()
//                .and()
//                .exceptionHandling()
                // 未登陆，请求处理
//                .authenticationEntryPoint((request, response, authException)->response.getWriter().write("authenticationEntryPoint"))
                .and()
                .csrf().disable()
                .httpBasic();
    }
}
